package com.pactera.madp.common.crypto.sm;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;

import java.util.Arrays;

public class SM3Utils {

    /**
     * SM3 签名
     *
     * @param sourceBytes 原始数组
     * @return 加密后的，32位数组
     */
    private static byte[] sign(byte[] sourceBytes) {
        SM3Digest digest = new SM3Digest();
        digest.update(sourceBytes, 0, sourceBytes.length);
        byte[] result = new byte[32];
        digest.doFinal(result, 0);
        return result;
    }

	/**
	 * 字符串 签名 64位十六进制字符串
	 *
	 * @param sourceBytes such as "yline".getBytes()
	 * @return such as 66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0
	 */
	public static String signHex(byte[] sourceBytes) {
		return HexUtil.encodeHexStr(sign(sourceBytes));
	}

	/**
	 * 字符串签名签名 base64字符串
	 * @param sourceBytes
	 * @return
	 */
	public static String signBase64(byte[] sourceBytes) {
		return Base64.encode(sign(sourceBytes));
	}

	/**
	 * 字符串 签名 64位十六进制字符串
	 *
	 * @param source 待签名字符串
	 * @return such as 66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0
	 */
	public static String signHex(String source){
		return signHex(StrUtil.bytes(source));
	}

	/**
	 * 字符串签名签名 base64字符串
	 * @param source	待签名字符串
	 * @return
	 */
	public static String signBase64(String source){
		return signBase64(StrUtil.bytes(source));
	}

	/**
	 * 签名效验
	 * @param sourceBytes	待签名二进制数据
	 * @param signBytes		待比较签名二进制数据
	 * @return
	 */
	public static boolean verify(byte[] sourceBytes, byte[] signBytes){
		return Arrays.equals(sign(sourceBytes), signBytes);
	}

	/**
	 * 签名效验
	 * @param source		待签名字符串
	 * @param signBytes		待比较签名二进制数据
	 * @return
	 */
	public static boolean verify(String source, byte[] signBytes){
		return verify(StrUtil.bytes(source), signBytes);
	}

	/**
	 * 签名效验
	 * @param source	待签名字符串
	 * @param sign		待比较签名[base64格式或十六进制格式]
	 * @return
	 */
	public static boolean verify(String source, String sign){
		return  verify(source, SecureUtil.decode(sign));
	}

}
